--wuqibo
--2021.2.7
--环形盒子抽奖驱动类
--[[
  使用方法:
    self.turntableDriverBox = TurntableDriverBox:new(8)
    self.turntableDriverBox:start(fromIndex, stopIndex, function(index, completed)
            self:ShowEffect(index)
        end
    )
    ● 设置跳过某个已经开过奖的索引
    self.turntableDriverBox::setIgnoreIndexes({5,6})
    ● 立即停止
    self.turntableDriverBox:stop()
    ● 对外只读方法：
    bool isRunning = self.turntableDriverBox:isRunning()
]]
local TurntableDriverBox = fb_class("TurntableDriverBox")

local function expoIn(t, b, c, d)
    if (t == 0) then
        return b
    else
        return c * math.pow(2, 10 * (t / d - 1)) + b
    end
end

function TurntableDriverBox:ctor(cellCount, roundCount, minDelay, maxDelay)
    self.cellCount = cellCount
    self.roundCount = roundCount or 3
    self.minDelay = minDelay or 0.05
    self.maxDelay = maxDelay or 0.5
end

function TurntableDriverBox:start(fromIndex, stopIndex, onRun, selfObject)
    if self._isRunning then
        return
    end
    self._isRunning = true
    local delayList = {}
    local stepsCount = self.cellCount * self.roundCount + stopIndex
    for i = 1, stepsCount do
        delayList[i] = expoIn(i, self.minDelay, self.maxDelay - self.minDelay, stepsCount)
    end
    self.currRun =
        coroutine.start(
        function()
            for i = fromIndex, self.cellCount do
                if not self:_isIgnoreIndex(i) then
                    coroutine.wait(delayList[1])
                    if onRun then
                        if selfObject then
                            onRun(selfObject, i, false)
                        else
                            onRun(i, false)
                        end
                    end
                end
            end
            for i = 1, stepsCount do
                local index = i
                while index > self.cellCount do
                    index = index - self.cellCount
                end
                if not self:_isIgnoreIndex(index) or i == stepsCount then
                    coroutine.wait(delayList[i])
                    if onRun then
                        if selfObject then
                            onRun(selfObject, index, i == stepsCount)
                        else
                            onRun(index, i == stepsCount)
                        end
                    end
                    if i == stepsCount then
                        coroutine.start(
                            function()
                                coroutine.wait(1)
                                self._isRunning = false
                            end
                        )
                    end
                end
            end
        end
    )
end

function TurntableDriverBox:stop()
    if self.currRun then
        coroutine.stop(self.currRun)
        self.currRun = nil
    end
    self._isRunning = false
end

function TurntableDriverBox:setIgnoreIndexes(ignoreIndexes)
    self.ignoreIndexes = {}
    if ignoreIndexes then
        for index, value in pairs(ignoreIndexes) do
            local isContains = false
            for _, v in pairs(self.ignoreIndexes) do
                if v == value then
                    isContains = true
                    break
                end
            end
            if not isContains then
                table.insert(self.ignoreIndexes, value)
            end
        end
    end
end

function TurntableDriverBox:_isIgnoreIndex(index)
    if self.ignoreIndexes then
        for key, value in pairs(self.ignoreIndexes) do
            if value == index then
                return true
            end
        end
    end
    return false
end

--对外函数：判断转盘是否在正式抽奖转动中
function TurntableDriverBox:isRunning()
    return self._isRunning
end

return TurntableDriverBox
